This way we can pass the command pool around.
And that allows us to allocate and submitcustom buffers.
And that is necessary to make staging images work.
if HAVE_VULKAN
gsk_private_vulan_source_h = \
gskvulkanbufferprivate.h \
+ gskvulkancommandpoolprivate.h \
gskvulkanimageprivate.h \
gskvulkanmemoryprivate.h \
gskvulkanpipelineprivate.h \
gskvulkanshaderprivate.h
gsk_private_vulkan_source_c = \
gskvulkanbuffer.c \
+ gskvulkancommandpool.c \
gskvulkanimage.c \
gskvulkanmemory.c \
gskvulkanpipeline.c \
--- /dev/null
+#include "config.h"
+
+#include "gskvulkancommandpoolprivate.h"
+#include "gskvulkanpipelineprivate.h"
+
+struct _GskVulkanCommandPool
+{
+ GdkVulkanContext *vulkan;
+
+ VkCommandPool vk_command_pool;
+};
+
+GskVulkanCommandPool *
+gsk_vulkan_command_pool_new (GdkVulkanContext *context)
+{
+ GskVulkanCommandPool *self;
+
+ self = g_slice_new0 (GskVulkanCommandPool);
+
+ self->vulkan = g_object_ref (context);
+
+ GSK_VK_CHECK (vkCreateCommandPool, gdk_vulkan_context_get_device (context),
+ &(const VkCommandPoolCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+ .queueFamilyIndex = gdk_vulkan_context_get_queue_family_index (self->vulkan),
+ .flags = 0
+ },
+ NULL,
+ &self->vk_command_pool);
+
+ return self;
+}
+
+void
+gsk_vulkan_command_pool_free (GskVulkanCommandPool *self)
+{
+ vkDestroyCommandPool (gdk_vulkan_context_get_device (self->vulkan),
+ self->vk_command_pool,
+ NULL);
+
+ g_slice_free (GskVulkanCommandPool, self);
+}
+
+void
+gsk_vulkan_command_pool_reset (GskVulkanCommandPool *self)
+{
+ GSK_VK_CHECK (vkResetCommandPool, gdk_vulkan_context_get_device (self->vulkan),
+ self->vk_command_pool,
+ 0);
+}
+
+VkCommandBuffer
+gsk_vulkan_command_pool_get_buffer (GskVulkanCommandPool *self)
+{
+ VkCommandBuffer command_buffer;
+
+ GSK_VK_CHECK (vkAllocateCommandBuffers, gdk_vulkan_context_get_device (self->vulkan),
+ &(VkCommandBufferAllocateInfo) {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .commandPool = self->vk_command_pool,
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = 1,
+ },
+ &command_buffer);
+
+ GSK_VK_CHECK (vkBeginCommandBuffer, command_buffer,
+ &(VkCommandBufferBeginInfo) {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ .flags = 0
+ });
+
+ return command_buffer;
+}
+
+void
+gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
+ VkCommandBuffer command_buffer,
+ VkFence fence)
+{
+ GSK_VK_CHECK (vkEndCommandBuffer, command_buffer);
+
+ GSK_VK_CHECK (vkQueueSubmit, gdk_vulkan_context_get_queue (self->vulkan),
+ 1,
+ &(VkSubmitInfo) {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .waitSemaphoreCount = 1,
+ .pWaitSemaphores = (VkSemaphore[1]) {
+ gdk_vulkan_context_get_draw_semaphore (self->vulkan)
+ },
+ .pWaitDstStageMask = (VkPipelineStageFlags []) {
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ },
+ .commandBufferCount = 1,
+ .pCommandBuffers = (VkCommandBuffer[1]) {
+ command_buffer
+ },
+ .signalSemaphoreCount = 1,
+ .pSignalSemaphores = (VkSemaphore[1]) {
+ gdk_vulkan_context_get_draw_semaphore (self->vulkan)
+ }
+ },
+ fence);
+}
+
--- /dev/null
+#ifndef __GSK_VULKAN_COMMAND_POOL_PRIVATE_H__
+#define __GSK_VULKAN_COMMAND_POOL_PRIVATE_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GskVulkanCommandPool GskVulkanCommandPool;
+
+GskVulkanCommandPool * gsk_vulkan_command_pool_new (GdkVulkanContext *context);
+void gsk_vulkan_command_pool_free (GskVulkanCommandPool *self);
+
+void gsk_vulkan_command_pool_reset (GskVulkanCommandPool *self);
+
+VkCommandBuffer gsk_vulkan_command_pool_get_buffer (GskVulkanCommandPool *self);
+void gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
+ VkCommandBuffer buffer,
+ VkFence fence);
+
+G_END_DECLS
+
+#endif /* __GSK_VULKAN_COMMAND_POOL_PRIVATE_H__ */
}
GskVulkanImage *
-gsk_vulkan_image_new_from_data_via_staging_buffer (GdkVulkanContext *context,
- VkCommandBuffer command_buffer,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+gsk_vulkan_image_new_from_data_via_staging_buffer (GdkVulkanContext *context,
+ GskVulkanCommandPool *command_pool,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
{
GskVulkanImage *self;
GskVulkanBuffer *staging;
+ VkCommandBuffer command_buffer;
guchar *mem;
staging = gsk_vulkan_buffer_new_staging (context, width * height * 4);
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ command_buffer = gsk_vulkan_command_pool_get_buffer (command_pool);
+
vkCmdPipelineBarrier (command_buffer,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
}
});
+ gsk_vulkan_command_pool_submit_buffer (command_pool, command_buffer, VK_NULL_HANDLE);
+
/* XXX: Is this okay or do we need to keep the staging image around until the commands execute */
gsk_vulkan_buffer_free (staging);
}
GskVulkanImage *
-gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
- VkCommandBuffer command_buffer,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
+ GskVulkanCommandPool *command_pool,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
{
GskVulkanImage *self, *staging;
+ VkCommandBuffer command_buffer;
staging = gsk_vulkan_image_new (context,
width,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ command_buffer = gsk_vulkan_command_pool_get_buffer (command_pool);
+
vkCmdPipelineBarrier (command_buffer,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
}
});
+ gsk_vulkan_command_pool_submit_buffer (command_pool, command_buffer, VK_NULL_HANDLE);
+
/* XXX: Is this okay or do we need to keep the staging image around until the commands execute */
g_object_unref (staging);
}
GskVulkanImage *
-gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
- VkCommandBuffer command_buffer,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
+ GskVulkanCommandPool *command_pool,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
{
+ VkCommandBuffer command_buffer;
GskVulkanImage *self;
+ command_buffer = gsk_vulkan_command_pool_get_buffer (command_pool);
+
self = gsk_vulkan_image_new (context,
width,
height,
}
});
+ gsk_vulkan_command_pool_submit_buffer (command_pool, command_buffer, VK_NULL_HANDLE);
+
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
return self;
}
GskVulkanImage *
-gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
- VkCommandBuffer command_buffer,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
+ GskVulkanCommandPool *command_pool,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
{
if (GSK_RENDER_MODE_CHECK (STAGING_BUFFER))
- return gsk_vulkan_image_new_from_data_via_staging_buffer (context, command_buffer, data, width, height, stride);
+ return gsk_vulkan_image_new_from_data_via_staging_buffer (context, command_pool, data, width, height, stride);
if (GSK_RENDER_MODE_CHECK (STAGING_IMAGE))
- return gsk_vulkan_image_new_from_data_via_staging_image (context, command_buffer, data, width, height, stride);
+ return gsk_vulkan_image_new_from_data_via_staging_image (context, command_pool, data, width, height, stride);
else
- return gsk_vulkan_image_new_from_data_directly (context, command_buffer, data, width, height, stride);
+ return gsk_vulkan_image_new_from_data_directly (context, command_pool, data, width, height, stride);
}
GskVulkanImage *
#include <gdk/gdk.h>
+#include "gsk/gskvulkancommandpoolprivate.h"
+
G_BEGIN_DECLS
#define GSK_TYPE_VULKAN_IMAGE (gsk_vulkan_image_get_type ())
gsize width,
gsize height);
GskVulkanImage * gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
- VkCommandBuffer command_buffer,
+ GskVulkanCommandPool *pool,
guchar *data,
gsize width,
gsize height,
#include "gskrendererprivate.h"
#include "gskvulkanbufferprivate.h"
+#include "gskvulkancommandpoolprivate.h"
#include "gskvulkanpipelineprivate.h"
#include "gskvulkanrenderpassprivate.h"
VkRect2D scissor;
GHashTable *framebuffers;
- VkCommandPool command_pool;
+ GskVulkanCommandPool *command_pool;
VkFence fence;
VkRenderPass render_pass;
GskVulkanPipelineLayout *layout;
gsize n_descriptor_sets;
GskVulkanPipeline *pipelines[GSK_VULKAN_N_PIPELINES];
- VkCommandBuffer command_buffer;
-
GskVulkanImage *target;
GSList *render_passes;
device = gdk_vulkan_context_get_device (self->vulkan);
- GSK_VK_CHECK (vkCreateCommandPool, device,
- &(const VkCommandPoolCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
- .queueFamilyIndex = gdk_vulkan_context_get_queue_family_index (self->vulkan),
- .flags = 0
- },
- NULL,
- &self->command_pool);
-
+ self->command_pool = gsk_vulkan_command_pool_new (self->vulkan);
GSK_VK_CHECK (vkCreateFence, device,
&(VkFenceCreateInfo) {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
for (l = self->render_passes; l; l = l->next)
{
- gsk_vulkan_render_pass_upload (l->data, self, self->command_buffer);
+ gsk_vulkan_render_pass_upload (l->data, self, self->command_pool);
}
}
VkSampler sampler)
{
GskVulkanBuffer *buffer;
+ VkCommandBuffer command_buffer;
GSList *l;
gsk_vulkan_render_prepare_descriptor_sets (self, sampler);
+ command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
+
buffer = gsk_vulkan_render_collect_vertices (self);
- vkCmdSetViewport (self->command_buffer,
+ vkCmdSetViewport (command_buffer,
0,
1,
&(VkViewport) {
.maxDepth = 1
});
- vkCmdSetScissor (self->command_buffer,
+ vkCmdSetScissor (command_buffer,
0,
1,
&self->scissor);
- vkCmdBeginRenderPass (self->command_buffer,
+ vkCmdBeginRenderPass (command_buffer,
&(VkRenderPassBeginInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = self->render_pass,
},
VK_SUBPASS_CONTENTS_INLINE);
- vkCmdBindVertexBuffers (self->command_buffer,
+ vkCmdBindVertexBuffers (command_buffer,
0,
1,
(VkBuffer[1]) {
for (l = self->render_passes; l; l = l->next)
{
- gsk_vulkan_render_pass_draw (l->data, self, self->layout, self->command_buffer);
+ gsk_vulkan_render_pass_draw (l->data, self, self->layout, command_buffer);
}
- vkCmdEndRenderPass (self->command_buffer);
-
- gsk_vulkan_buffer_free (buffer);
-}
+ vkCmdEndRenderPass (command_buffer);
-void
-gsk_vulkan_render_submit (GskVulkanRender *self)
-{
- GSK_VK_CHECK (vkEndCommandBuffer, self->command_buffer);
+ gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, self->fence);
- GSK_VK_CHECK (vkQueueSubmit, gdk_vulkan_context_get_queue (self->vulkan),
- 1,
- &(VkSubmitInfo) {
- .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = (VkSemaphore[1]) {
- gdk_vulkan_context_get_draw_semaphore (self->vulkan)
- },
- .pWaitDstStageMask = (VkPipelineStageFlags []) {
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- },
- .commandBufferCount = 1,
- .pCommandBuffers = &self->command_buffer,
- .signalSemaphoreCount = 1,
- .pSignalSemaphores = (VkSemaphore[1]) {
- gdk_vulkan_context_get_draw_semaphore (self->vulkan)
- }
- },
- self->fence);
+ gsk_vulkan_buffer_free (buffer);
if (GSK_RENDER_MODE_CHECK (SYNC))
{
GSK_VK_CHECK (vkResetFences, device,
1,
&self->fence);
- GSK_VK_CHECK (vkResetCommandPool, device,
- self->command_pool,
- 0);
+
+ gsk_vulkan_command_pool_reset (self->command_pool);
g_hash_table_remove_all (self->descriptor_set_indexes);
vkDestroyFence (device,
self->fence,
NULL);
- vkDestroyCommandPool (device,
- self->command_pool,
- NULL);
+
+ gsk_vulkan_command_pool_free (self->command_pool);
g_slice_free (GskVulkanRender, self);
}
gsk_vulkan_render_reset (GskVulkanRender *self,
GskVulkanImage *target)
{
- VkDevice device;
-
gsk_vulkan_render_cleanup (self);
self->target = g_object_ref (target);
gsk_vulkan_render_compute_mvp (self);
-
- device = gdk_vulkan_context_get_device (self->vulkan);
-
- GSK_VK_CHECK (vkAllocateCommandBuffers, device,
- &(VkCommandBufferAllocateInfo) {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
- .commandPool = self->command_pool,
- .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
- .commandBufferCount = 1,
- },
- &self->command_buffer);
-
- GSK_VK_CHECK (vkBeginCommandBuffer, self->command_buffer,
- &(VkCommandBufferBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
- .flags = 0
- });
}
GskRenderer *
gsk_vulkan_render_draw (render, self->sampler);
- gsk_vulkan_render_submit (render);
-
#ifdef G_ENABLE_DEBUG
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
}
GskVulkanImage *
-gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
- GskTexture *texture,
- VkCommandBuffer command_buffer)
+gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
+ GskTexture *texture,
+ GskVulkanCommandPool *command_pool)
{
GskVulkanTextureData *data;
cairo_surface_t *surface;
surface = gsk_texture_download (texture);
image = gsk_vulkan_image_new_from_data (self->vulkan,
- command_buffer,
+ command_pool,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
GskVulkanImage * gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
GskTexture *texture,
- VkCommandBuffer command_buffer);
+ GskVulkanCommandPool *command_pool);
G_END_DECLS
}
static void
-gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
- GskVulkanOpRender *op,
- GskVulkanRender *render,
- VkCommandBuffer command_buffer)
+gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
+ GskVulkanOpRender *op,
+ GskVulkanRender *render,
+ GskVulkanCommandPool *command_pool)
{
graphene_rect_t bounds;
cairo_surface_t *surface;
cairo_destroy (cr);
op->source = gsk_vulkan_image_new_from_data (self->vulkan,
- command_buffer,
+ command_pool,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
}
void
-gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
- GskVulkanRender *render,
- VkCommandBuffer command_buffer)
+gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
+ GskVulkanRender *render,
+ GskVulkanCommandPool *command_pool)
{
GskVulkanOp *op;
guint i;
switch (op->type)
{
case GSK_VULKAN_OP_FALLBACK:
- gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, command_buffer);
+ gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, command_pool);
break;
case GSK_VULKAN_OP_SURFACE:
{
cairo_surface_t *surface = gsk_cairo_node_get_surface (op->render.node);
op->render.source = gsk_vulkan_image_new_from_data (self->vulkan,
- command_buffer,
+ command_pool,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
{
op->render.source = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)),
gsk_texture_node_get_texture (op->render.node),
- command_buffer);
+ command_pool);
gsk_vulkan_render_add_cleanup_image (render, op->render.source);
}
break;
#include <gdk/gdk.h>
#include <gsk/gskrendernode.h>
+#include "gsk/gskvulkancommandpoolprivate.h"
#include "gsk/gskvulkanrenderprivate.h"
G_BEGIN_DECLS
void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
GskVulkanRender *render,
- VkCommandBuffer command_buffer);
+ GskVulkanCommandPool *command_pool);
gsize gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self);
gsize gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,